package ylg.com.cn.mdplayer.persenter;

import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.File;
import java.util.ArrayList;
import java.util.List;


import rx.Observable;
import rx.Scheduler;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.observables.GroupedObservable;
import rx.schedulers.Schedulers;
import ylg.com.cn.mdplayer.model.CacheManager;
import ylg.com.cn.mdplayer.model.FileBean;
import ylg.com.cn.mdplayer.model.VideoBean;
import ylg.com.cn.mdplayer.mvp.BasePresenter;
import ylg.com.cn.mdplayer.utils.FileUtils;
import ylg.com.cn.mdplayer.view.IMVPView;

/**
 * Created by MyPC on 2017/1/23.
 */

public class VideoFilePresenter extends BasePresenter<IMVPView> {

    private boolean inited = false;
    private Gson gson = new Gson();
    private String cacheStr = "";
    /**包含有视频文件夹集合**/
    private List<FileBean> fileBeans = new ArrayList<FileBean>();
    /**
     * 某一个文件夹中所有的视频文件
     **/
    private List<VideoBean> videoBeans = new ArrayList<VideoBean>();
    private List<File> files = new ArrayList<File>();
    private static final String cacheKey = "fileBeansCacheData";
    public void getFileData(boolean isRefresh){
        fileBeans.clear();
        files.clear();
        cacheStr = CacheManager.getInstance().getAsString(cacheKey);
        if(isRefresh){
            cacheStr = null;
        }
        /**如果有缓存数据那就先显示缓存数据**/
        if(cacheStr != null && !TextUtils.isEmpty(cacheStr)){
            Gson gson = new Gson();
            // json转为带泛型的list
            List<FileBean> dataList = gson.fromJson(cacheStr,
                    new TypeToken<List<FileBean>>() {
                    }.getType());
            if (dataList.size()>0){
                if(VideoFilePresenter.this.getMvpView() != null){
                    VideoFilePresenter.this.getMvpView().getDataSuccess(dataList);
                    inited = true;
                    VideoFilePresenter.this.getMvpView().hideProgress();
                }
            }else{
                inited = false;
            }
        }else{
            inited = false;
            if(VideoFilePresenter.this.getMvpView() != null){
                VideoFilePresenter.this.getMvpView().showProgress();
            }
        }
        File rootFile = Environment.getExternalStorageDirectory();
        if (rootFile!=null){
            this.addSubscriberToCompositeSubscription((Subscription) Observable.just(rootFile).flatMap(new Func1<File, Observable<File>>() {

                @Override
                public Observable<File> call(File file) {
                    return listFiles(file);
                }
            }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<File>() {
                @Override
                public void onCompleted() {
                    groupByFiles(files);
                }

                @Override
                public void onError(Throwable e) {
                    if(VideoFilePresenter.this.getMvpView() != null){
                        VideoFilePresenter.this.getMvpView().getDataError(e);
                    }
                }

                @Override
                public void onNext(File file) {
                    files.add(file);
                }
            }));
        }
    }

    private void groupByFiles(List<File> datas){
        this.addSubscriberToCompositeSubscription(Observable.from(datas).groupBy(new Func1<File, File>() {
            @Override
            public File call(File file) {
                /**以视频文件的父文件夹路径进行分组**/
                return file.getParentFile();
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<GroupedObservable<File, File>>() {
                    @Override
                    public void onCompleted() {
                        Log.d("danxx", "groupBy onCompleted");
                        if(!inited){
                            if(VideoFilePresenter.this.getMvpView() != null){
                                VideoFilePresenter.this.getMvpView().getDataSuccess(fileBeans);
                                VideoFilePresenter.this.getMvpView().hideProgress();
                                inited = true;
                            }
                            String cacheStr = gson.toJson(fileBeans);
                            if(!TextUtils.isEmpty(cacheStr)){
                                CacheManager.getInstance().remove(cacheKey);
                                CacheManager.getInstance().put(cacheKey, cacheStr);
                            }
                        }else{
                            String cacheStr = gson.toJson(fileBeans);
                            if(!TextUtils.isEmpty(cacheStr)){
                                CacheManager.getInstance().remove(cacheKey);
                                CacheManager.getInstance().put(cacheKey ,cacheStr);
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        if(VideoFilePresenter.this.getMvpView() != null){
                            VideoFilePresenter.this.getMvpView().getDataError(e);
                            VideoFilePresenter.this.getMvpView().hideProgress();
                        }
                    }

                    @Override
                    public void onNext(final GroupedObservable<File, File> fileGroupedObservable) {
                        fileGroupedObservable.subscribe(new Subscriber<File>() {
                            int count = 0;
                            String parentName;
                            @Override
                            public void onCompleted() {
                                fileBeans.add(new FileBean(String.valueOf(fileGroupedObservable.getKey()), parentName, count));
                                count = 0;
                                parentName = null;
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(File file) {
                                count++;
                                parentName = file.getParentFile().getName();
                            }
                        });
                    }
                }));
    }
    /**
     * rxjava递归查询内存中的视频文件
     * 在此方法中应该可以做groupby操作，这样能简化操作，日后再研究
     * @param f
     * @return
     */
    public Observable<File> listFiles(final File f){
        if(f.isDirectory()){
            return Observable.from(f.listFiles())
                    .flatMap(new Func1<File, Observable<File>>() {
                        @Override
                        public Observable<File> call(File file) {
                            /**如果是文件夹就递归**/
                            return listFiles(file);
                        }
                    });
        } else {
            /**filter操作符过滤视频文件,是视频文件就通知观察者**/
            return Observable.just(f)
                    .filter(new Func1<File, Boolean>() {
                        @Override
                        public Boolean call(File file) {
                            return f.exists() && f.canRead() && FileUtils.isVideo(f);
                        }
                    });
        }
    }
}
